﻿@*
//------------------------------------------------------------------------------
//  此代码版权声明为全文件覆盖，如有原作者特别声明，会在下方手动补充
//  此代码版权（除特别声明外的代码）归作者本人Diego所有
//  源代码使用协议遵循本仓库的开源协议及附加协议
//  Gitee源代码仓库：https://gitee.com/diego2098/ThingsGateway
//  Github源代码仓库：https://github.com/kimdiego2098/ThingsGateway
//  使用文档：https://diego2098.gitee.io/thingsgateway-docs/
//  QQ群：605534569
//------------------------------------------------------------------------------
*@

@page "/tgruntime/collectdevicevariable"
@namespace ThingsGateway.Web.Page
@using System.Linq.Expressions;
@using BlazorComponent;
@using Furion.DataValidation;
@using Furion;
@using Mapster;
@using Masa.Blazor.Presets;
@using System.IO;
@using TouchSocket.Core;
@attribute [Authorize]
@inject MasaBlazor MasaBlazor
@attribute [RolePermission]
@inherits CultureComponentBase
@inject UserResoures UserResoures
@layout MainLayout

<MRow>
    <MCol Md=2 Cols="12">
        <MCard Class="ma-2" Style="height: calc(100vh - 200px)">
            <MCardTitle>
                <MTextField Dense Style="max-width:200px;" HideDetails=@("auto") Class="mx-2 my-1" @bind-Value="_searchName"
                            Outlined Label=@typeof(CollectDevice).GetDescription(nameof(CollectDevice.DeviceGroup)) />
            </MCardTitle>
            <MTreeview Style="height: calc(100vh - 320px);overflow-y:auto" Dense TItem="DeviceTree" TKey="string" Active="_searchModel.DeviceName?.StringToList()" OpenOnClick ActiveChanged=@((async a=>
                       {
                       if(this._searchModel.DeviceName!= a.FirstOrDefault())
                       {
                       this._searchModel.DeviceName= a.FirstOrDefault();
                       await datatableQuery();
                       }
                       }) )
                       Items="_deviceGroups" ItemText="r=>r.Name" ItemChildren="r=>r.Childrens"
                       Search="@_searchName"
                       Activatable ItemKey=@(r=>r.Name)>
            </MTreeview>
        </MCard>
    </MCol>
    <MCol Md=10 Cols="12">
        <div style="height: calc(100vh - 200px)">

            <AppDataTable @ref="_datatable" TItem="CollectVariableRunTime" SearchItem="VariablePageInput"
                          AddItem="object" EditItem="object"
                          SearchModel="_searchModel"
                          QueryCall="QueryCall"
                          FilterHeaders="FilterHeaders" Filters="Filters" ShowDetailButton IsShowOperCol=true
                                ShowQueryButton>
                <SearchTemplate>
                    <MTextField Dense Style="max-width:200px;" HideDetails=@("auto") Class="my-1  mx-2 " @bind-Value="context.Name" Clearable
                                        Outlined Label=@context.Description(x => x.Name) />
                    <MTextField Dense Style="max-width:200px;" HideDetails=@("auto") Class="my-1  mx-2 " @bind-Value="context.DeviceName" Clearable
                                        Outlined Label=@context.Description(x => x.DeviceName) />
                </SearchTemplate>

                <ItemColOperTemplate>
                    <MButton Text Disabled=@(!UserResoures.IsHasButtonWithRole("tgcollectdeviceedit")) Class="my-1  mx-2" OnClick=@(() => Write(context.Item))>
                        @T("写入")
                    </MButton>
                </ItemColOperTemplate>
                <ItemColTemplate>
                    @switch (context.Header.Value)
                    {

                        case nameof(context.Item.Quality):
                            <EnableChip Value="context.Item.Quality==192" DisabledLabel=@context.Item.Quality.ToString() EnabledLabel=@context.Item.Quality.ToString()>
                            </EnableChip>
                            break;
                        default:
                            @context.Value
                            break;

                    }

                </ItemColTemplate>

            </AppDataTable>

        </div>
    </MCol>
</MRow>

@code {
    string _searchName;
    List<DeviceTree> _deviceGroups = new();


    [Parameter]
    [SupplyParameterFromQuery]
    public string DeviceName
    {
        get;
        set;
    }

    VariablePageInput _searchModel { get; set; } = new();
    private IAppDataTable _datatable;
    CollectDeviceWorker CollectDeviceHostService { get; set; }
    private System.Timers.Timer DelayTimer;
    protected override async Task OnParametersSetAsync()
    {
        if (_searchModel.DeviceName != DeviceName && !DeviceName.IsNullOrEmpty())
        {
            _searchModel.DeviceName = DeviceName;
            await datatableQuery();
        }
        CollectDeviceHostService = ServiceExtension.GetBackgroundService<CollectDeviceWorker>();

        _deviceGroups = CollectDeviceServiceHelpers.GetTree(CollectDeviceHostService.CollectDeviceRunTimes.Adapt<List<CollectDevice>>());

        await base.OnParametersSetAsync();
    }
    protected override async Task OnInitializedAsync()
    {
        DelayTimer = new System.Timers.Timer(1000);
        DelayTimer.Elapsed += timer_Elapsed;
        DelayTimer.AutoReset = true;
        DelayTimer.Start();
        await base.OnInitializedAsync();
    }
    async void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
    {
        await InvokeAsync(StateHasChanged);
    }
    protected override async Task DisposeAsync(bool disposing)
    {
        await base.DisposeAsync(disposing);
        DelayTimer?.SafeDispose();
    }
    private async Task datatableQuery()
    {
        if (_datatable != null)
            await _datatable?.QueryClickAsync();
    }
    [Inject]
    RpcSingletonService rpcCore { get; set; }
    private async Task Write(CollectVariableRunTime collectVariableRunTime)
    {
        var confirm = await PopupService.PromptAsync(T("写入"),
        $"输入变量{collectVariableRunTime.Name}的写入值");
        if (confirm != null)
        {
            var data = await rpcCore?.InvokeDeviceMethodAsync($"BLAZOR-{UserResoures.CurrentUser.Account}-{App.HttpContext.Connection.RemoteIpAddress.MapToIPv4().ToString()}", new NameValue { Name = collectVariableRunTime.Name, Value = confirm },System.Threading.CancellationToken.None, true);
            if (data.IsSuccess)
            {
                await InvokeAsync(async () => await PopupService.EnqueueSnackbarAsync(data.Message, AlertTypes.Success));
            }
            else
            {
                await InvokeAsync(async () => await PopupService.EnqueueSnackbarAsync(data.Message, AlertTypes.Warning));
            }
        }
    }

    private void FilterHeaders(List<DataTableHeader<CollectVariableRunTime>> datas)
    {
        datas.RemoveWhere(it => it.Value == nameof(CollectVariableRunTime.CreateUserId));
        datas.RemoveWhere(it => it.Value == nameof(CollectVariableRunTime.UpdateUserId));

        datas.RemoveWhere(it => it.Value == nameof(CollectVariableRunTime.IsDelete));
        datas.RemoveWhere(it => it.Value == nameof(CollectVariableRunTime.ExtJson));
        datas.RemoveWhere(it => it.Value == nameof(CollectVariableRunTime.Id));
        datas.RemoveWhere(it => it.Value == nameof(CollectVariableRunTime.VariablePropertys));
        datas.RemoveWhere(it => it.Value == nameof(CollectVariableRunTime.DeviceId));
        datas.RemoveWhere(it => it.Value == nameof(CollectVariableRunTime.VariableValueChange));
        datas.RemoveWhere(it => it.Value == nameof(CollectVariableRunTime.ThingsGatewayBitConverter));
        datas.RemoveWhere(it => it.Value == nameof(CollectVariableRunTime.StringBcdFormat));
        datas.RemoveWhere(it => it.Value == nameof(CollectVariableRunTime.DataType));
        datas.RemoveWhere(it => it.Value == nameof(CollectVariableRunTime.EventTime));
        datas.RemoveWhere(it => it.Value == nameof(CollectVariableRunTime.EventTypeEnum));
        datas.RemoveWhere(it => it.Value == nameof(CollectVariableRunTime.CollectDeviceRunTime));

        datas.RemoveWhere(it => it.Value.Contains("His"));
        datas.RemoveWhere(it => it.Value.Contains("Alarm"));
        datas.RemoveWhere(it => it.Value.Contains("RestrainExpressions"));

        foreach (var item in datas)
        {
            item.Sortable = false;
            item.Filterable = false;
            item.Divider = false;
            item.Align = DataTableHeaderAlign.Start;
            item.CellClass = " table-minwidth ";
            switch (item.Value)
            {
                case nameof(CollectVariableRunTime.Name):
                    item.Sortable = true;
                    break;
                case nameof(CollectVariableRunTime.DeviceName):
                    item.Sortable = true;
                    break;
                case nameof(CollectVariableRunTime.VariableAddress):
                    item.Sortable = true;
                    break;
                case nameof(CollectVariableRunTime.OtherMethod):
                    item.Sortable = true;
                    break;
                case nameof(CollectVariableRunTime.ChangeTime):
                    item.Sortable = true;
                    break;
                case nameof(CollectVariableRunTime.Quality):
                    item.Sortable = true;
                    break;
                case nameof(CollectVariableRunTime.ReadExpressions):
                    item.Sortable = true;
                    break;
            }
        }
    }

    private void Filters(List<Filters> datas)
    {
        foreach (var item in datas)
        {
            switch (item.Key)
            {
                case nameof(CollectVariableRunTime.CreateTime):
                case nameof(CollectVariableRunTime.UpdateTime):
                case nameof(CollectVariableRunTime.CreateUser):
                case nameof(CollectVariableRunTime.UpdateUser):
                    item.Value = false;
                    break;
            }
        }
    }

    private async Task<SqlSugarPagedList<CollectVariableRunTime>> QueryCall(VariablePageInput input)
    {
        var devices = CollectDeviceHostService.CollectDeviceRunTimes.SelectMany(it => it.DeviceVariableRunTimes).ToList();
        var data = await devices
    .WhereIf(!input.DeviceName.IsNullOrEmpty(), a => a.DeviceName == input.DeviceName)
    .WhereIf(!input.Name.IsNullOrEmpty(), a => a.Name.Contains(input.Name)).ToList()
    .ToPagedListAsync(input);
        return data;


    }
}
